package com.letv.ads.view;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebSettings.LayoutAlgorithm;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.letv.adlib.managers.status.ad.AdStatusManager;
import com.letv.adlib.sdk.types.AdElementMime;
import com.letv.ads.AdsManager;
import com.letv.android.sdk.R;
import com.letv.ads.util.AdJSBridge;
import com.letv.ads.util.LogInfo;

public class AdWebView extends WebView implements IAdView {
    private static final String TAG = "AdWebView";
    private AdElementMime mAdElementMime;
    private AdStatusManager mAdStatusManager;
    private boolean needSendExposure = true;
    private boolean mHasClosed = true;
    private AdWebviewEventListener mAdWebviewEventListener;
    private AdMaterialLoadListener mAdMaterialLoadListener;
    private AdViewOnclickListenr mAdViewOnclickListenr;
    private AdPlayStateListener mAdPlayStateListener;
    private boolean hasExposure = false;
    private AdJSBridge jsBridge;
    private boolean isLoadFailed;
    private String mAdUrl;
    private Context mContext;
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case AdJSBridge.CLOSE_WEBVIEW:
                    if (null != mAdWebviewEventListener) {
                        mAdWebviewEventListener.onCloseWebView();
                    }
                    break;
                case AdJSBridge.REFRESH_WEBVIEW:
                    AdWebView.this.reload();
                    break;
                case AdJSBridge.FULLSCREEN_WEBVIEW:
                    if (null != mAdWebviewEventListener) {
                        mAdWebviewEventListener.onFullScreen();
                    }
                    break;
                case AdJSBridge.RESTORE_SIZE_WEBVIEW:
                    if (null != mAdWebviewEventListener) {
                        mAdWebviewEventListener.onRestoreSize();
                    }
                    break;
            }
            super.handleMessage(msg);
        }
    };

    public static abstract class AdWebviewEventListener {
        public void onPageStarted(WebView view, String url) {
        }

        public void onPageFinished(WebView view, String url) {
        }

        public void onProgressChanged(WebView view, int newProgress) {
        }

        // used for interacting with JS
        public void onCloseWebView() {

        }

        // used for interacting with JS
        public void onRestoreSize() {

        }

        // used for interacting with JS
        public void onFullScreen() {

        }
    }

    public AdWebView(Context context) {
        super(context, null);
        initAttr(context, null);
    }

    public AdWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttr(context, attrs);
    }

    @SuppressLint("SetJavaScriptEnabled")
    private void initAttr(Context context, AttributeSet attrs) {
        mContext = context;
        WebSettings webSettings = this.getSettings();
        boolean appCacheEnabled = true;
        boolean domStorageEnabled = true;
        boolean clearCache = false;
        boolean javaScriptEnabled = true;
        if (null != attrs) {
            TypedArray ta = context.obtainStyledAttributes(attrs,
                    R.styleable.AdWebview);
            appCacheEnabled = ta.getBoolean(
                    R.styleable.AdWebview_appCacheEnabled, true);
            domStorageEnabled = ta.getBoolean(
                    R.styleable.AdWebview_domStorageEnabled, true);
            clearCache = ta.getBoolean(R.styleable.AdWebview_clearCache, false);
            javaScriptEnabled = ta.getBoolean(
                    R.styleable.AdWebview_javaScriptEnabled, true);
            needSendExposure = ta.getBoolean(R.styleable.adview_needexposure,
                    true);
        }
        webSettings.setAppCacheEnabled(appCacheEnabled);
        webSettings.setDomStorageEnabled(domStorageEnabled);
        webSettings.setJavaScriptEnabled(javaScriptEnabled);
        webSettings.setDefaultTextEncodingName("GBK");
        webSettings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
        webSettings.setUseWideViewPort(true);
        webSettings.setLoadWithOverviewMode(true);
        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        setWebViewClient(new LetvWebViewClient());
        setWebChromeClient(new LetvWebViewChromeClient());
        if (null != AdsManager.getInstance().iAdJSBridge) {
            AdsManager.getInstance().iAdJSBridge.setJSBridge(
                    (Activity) context, this, mHandler, null);
        }
        jsBridge = new AdJSBridge(mAdElementMime);
        jsBridge.setJSBridge(context, this, mHandler, null);
    }

    public void setWebEventListener(
            AdWebviewEventListener adWebviewEventListener) {
        mAdWebviewEventListener = adWebviewEventListener;
    }

    public void showAD(final AdElementMime adInfo) {
        LogInfo.log(TAG, "showAD adInfo=" + adInfo);
        if (null != adInfo) {
            isLoadFailed = false;
            mAdElementMime = adInfo;
            // 传入ad对象
            jsBridge.setAdElement(mAdElementMime);
            loadUrl(adInfo.mediaFileUrl);
            mAdUrl = adInfo.mediaFileUrl;
            setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if (MotionEvent.ACTION_UP == event.getAction()) {
                        if (null != mAdViewOnclickListenr) {
                            mAdViewOnclickListenr.onADClick(adInfo);
                        }
                    }
                    return false;
                }
            });
        }
    }

    @Override
    public void closeAD() {
        if (mHasClosed) {
            return;
        } else {
            mHasClosed = true;
        }
        setVisibility(GONE);
        if (null != mAdStatusManager) {
            mAdStatusManager.onAdClosed();
        }
    }

    private class LetvWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            LogInfo.log(TAG, "shouldOverrideUrlLoading url=" + url);
            LetvWebViewActivity.launch(mContext, url, "广告");
            return true;
        }

        /*
         * (non-Javadoc)
         * 
         * @see
         * android.webkit.WebViewClient#onReceivedError(android.webkit.WebView,
         * int, java.lang.String, java.lang.String)
         */
        @Override
        public void onReceivedError(WebView view, int errorCode,
                String description, String failingUrl) {
            isLoadFailed = false;
            LogInfo.log(TAG, "onReceivedError description=" + description);
            super.onReceivedError(view, errorCode, description, failingUrl);
            if (null != mAdMaterialLoadListener && failingUrl.equals(mAdUrl)) {
                mAdMaterialLoadListener.onLoadFailed();
            }
        }

        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            LogInfo.log(TAG, "onPageFinished url=" + url);
        }
    }

    private class LetvWebViewChromeClient extends WebChromeClient {

        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
            LogInfo.log(TAG, "onProgressChanged  newProgress=" + newProgress);
            if (null != mAdWebviewEventListener) {
                mAdWebviewEventListener.onProgressChanged(view, newProgress);
            }
            // if (isLoadFailed) {
            // LogInfo.log(TAG, "onPageStarted load failed");
            // return;
            // }
            if (null == mAdStatusManager) {
                mAdStatusManager = new AdStatusManager(mAdElementMime);
            }
            if (null != mAdElementMime
                    && (!mAdElementMime.hadExposed || !mAdElementMime
                            .isComplexAD()) && !hasExposure && newProgress > 0) {
                // webview开始加载时,开始发曝光
                if (null != mAdPlayStateListener) {
                    Bundle bundle = new Bundle();
                    bundle.putInt(KEY_STATE, PLAY_STATE_STARTED);
                    mAdPlayStateListener.onADPlayStateChange(bundle);
                }
                mAdElementMime.hadExposed = true;
                // onProgressChanged会调用多次，避免非法曝光
                hasExposure = true;
                mAdStatusManager.onAdPlayStart();
                if (null != mAdWebviewEventListener) {
                    mAdWebviewEventListener.onPageStarted(view, mAdUrl);
                }
                if (null != mAdMaterialLoadListener) {
                    mAdMaterialLoadListener.onLoadComplete();
                }
            }
        }

    }

    @Override
    protected void onVisibilityChanged(View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        LogInfo.log(TAG, "onVisibilityChanged changedView=" + changedView
                + "  visibility=" + visibility);
        if (null != jsBridge) {
            if (visibility == View.VISIBLE) {
                jsBridge.onWebviewShow();
            } else {
                jsBridge.onWebviewHide();
            }
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        LogInfo.log(TAG, "onDetachedFromWindow ");
        if (null != jsBridge) {
            jsBridge.onDestory();
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.letv.ads.view.IAdView#setAdOnClickListener(com.letv.ads.view.
     * AdViewOnclickListenr)
     */
    @Override
    public void setAdOnClickListener(
            final AdViewOnclickListenr adViewOnclickListenr) {
        mAdViewOnclickListenr = adViewOnclickListenr;
    }

    /*
     * 
     * @see
     * com.letv.ads.view.IAdView#setAdMaterialDownloadListener(com.letv.ads.
     * view.IAdView.AdMaterialDownloadListener)
     */
    @Override
    public void setAdMaterialLoadListener(
            AdMaterialLoadListener adMaterialDownloadListener) {
        mAdMaterialLoadListener = adMaterialDownloadListener;
    }

    @Override
    public void setAdPlayStateListener(AdPlayStateListener adPlayStateListener) {
        mAdPlayStateListener = adPlayStateListener;
    }
}
